#include "../head/mainHead.h"

// 进程号选择
void processNumSele(char* processNum){
    while(*processNum != '0'){
        processNumSeleMenu(processNum);
        if(*processNum == '1' || *processNum == '2' || *processNum == '3' || *processNum == '4' ){
            break;
        }
        system("cls");
    }
}

// 输入进程名字
void pnameIn(int processNumInt){
    for(int i = 0; i < 10; i++){
        p[processNumInt].PNAME[i] = '0';
    }
    printf("|请输入第%d个进程名字-> ",processNumInt);
    scanf("%s", p[processNumInt].PNAME);
}

// 输入进程到达时间
void pTaIn(int processNumInt){
    for(int i = 0; i < 5; i++){
        p[processNumInt].Ta[i] = '+';
    }
    printf("|请输入第%d个进程到达时间(英文 24小时制)-> ",processNumInt);
    scanf("%s", p[processNumInt].Ta);
    while(p[processNumInt].Ta[1] != ':' && p[processNumInt].Ta[2] != ':'){
        printf("+------------------------------------------+\n");
        printf("|---输入不合法~注意是英文字符下的24进制哟~~|\n");
        printf("+------------------------------------------+\n");
        for(int i = 0; i < 5; i++){     //将进程运行时间初始化
            p[processNumInt].Ta[i] = '0';
        }
        printf("|请重新输入-> ");
        scanf("%s", p[processNumInt].Ta);
    }
}

// 输入进程运行时间
void pTrIn(int processNumInt){
    printf("|请输入第%d个进程运行时间(分钟)-> ",processNumInt);
    scanf("%d", &p[processNumInt].Tr);    
}

// 输入进程优先级
void pPriority(int processNumInt){
    printf("|请输入第%d个进程优先级(1~9递增)-> ",processNumInt);
    fflush(stdin);
    char tmp = '+';
    scanf("%c",&tmp);
    while(tmp < '1' || tmp > '9'){
        printf("+------------------------------------------+\n");
        printf("|----输入不合法~注意进程优先级区间是1~9哟~~|\n");
        printf("+------------------------------------------+\n");
        printf("|请重新输入-> ");
        fflush(stdin);
        scanf("%c",&tmp);
    }
    p[processNumInt].Priority = tmp - '0';
}

// 输入单个进程信息
void processInSin(char processNum){
    int processNumInt = processNum - '0';
    if(processNumInt < 1 || processNumInt > 4){
        printf("|该进程不存在~请重新输入~~");
        for(int i = 3; i > 0; i--){
            printf("|-%d秒后返回~~", i);
            Sleep(1000);
        }
        return; 
    }
    printf("+-----------------------------------------------------+\n");
    p[processNumInt].PID = processNumInt;//进程号
    pnameIn(processNumInt);//输入进程名
    pTaIn(processNumInt);//输入进程到达时间
    pTrIn(processNumInt);//输入进程运行时间
    pPriority(processNumInt);//输入进程优先级
    printf("+-----------------------------------------------------+\n");    
}

// 批量输入所有进程信息
void processInAll(){
    system("cls");
    for(char i = '1'; i < '5'; i++){
        fflush(stdin);      //清空缓冲区
        processInSin(i);
    }
}

// 修改单个进程属性
void processAltSingle(char processNum){
    int processNumInt = processNum - '0';
    char processAltNum = '+';
    while(processAltNum != '0'){
        processAltNumSeleMenu(&processAltNum);
        switch (processAltNum){
            case '0':{      //退出
                break;
            }
            case '1':{      //修改进程名
                pnameIn(processNumInt);            
                break;
            }
            case '2':{      //修改进程到达时间
                pTaIn(processNumInt);
                break;
            }
            case '3':{     //修改进程运行时间
                pTrIn(processNumInt);
                break;
            }
            case '4':{      //修改进程优先级
                pPriority(processNumInt);
                break;
            }
            default:
                break;
        }
        system("cls");
    }
}
// 输出单个属性
void attriPrintSingle(){
    char attriPrintSingleNUm = '+';
    while(attriPrintSingleNUm != '0'){
        attriPrintSingleMenu(&attriPrintSingleNUm);
        switch(attriPrintSingleNUm){
            case '0':{  
                break;
            }
            case '1':{      //输出进程号
                pidPrint();
                break;
            }
            case '2':{      //输出进程名
                pnamePrint();
                break;
            }
            case '3':{      //输出进程到达时间
                taPrint();
                break;
            }
            case '4':{
                tsPrint();
                break;
            }
            case '5':{      //输出进程运行时间
                trPrint();
                break;
            }
            case '6':{      //输出进程结束时间
                tfPrint();
                break;
            }
            case '7':{      //输出进程周转时间
                cycleTime();
                break;
            }
            case '8':{      //输出进程带权周转时间
                cycleTimeWithRight();
                break;
            }
            case '9':{      //输出进程优先级
                priorityPrint();
                break;
            }
            default :
                break;
        }
    }
}

// 时分格式转化为分钟格式
void arrStrsToMin(){
    arriveTime[0] = 1500;
    for(int i = 1; i < 5; i++){
        int hour = 0;
        int j;
        //获得小时
        for(j = 0; p[i].Ta[j] != ':'; j++){
            hour = hour * 10 + (p[i].Ta[j] - '0');
        }
        //获得分钟
        int min = 0;
        for(j = j + 1; j < 5 && (p[i].Ta[j] <= '9' && p[i].Ta[j] >= '0'); j++){
            min = min * 10 + (p[i].Ta[j] - '0');
        }
        arriveTime[i] = hour * 60 + min;
        // printf("hour = %d\tmin = %d\t\n",hour,min);
    }
}

// 结束时间分钟格式转化为时分格式
void endMinToStrs(){
    for(int i = 1; i < 5; i++){
        int hour = endTime[i] /60;
        int min = endTime[i] % 60;
        p[i].Tf[0] = (hour / 10) + '0';
        p[i].Tf[1] = (hour % 10) + '0';
        p[i].Tf[2] = ':';
        p[i].Tf[3] = (min / 10) + '0';
        p[i].Tf[4] = (min % 10) + '0';
    }
}

// 开始时间分钟格式转化为时分格式
void startMinToStrs(){
    for(int i = 1; i < 5; i++){
        int hour = startTime[i] /60;
        int min = startTime[i] % 60;
        p[i].Ts[0] = (hour / 10) + '0';
        p[i].Ts[1] = (hour % 10) + '0';
        p[i].Ts[2] = ':';
        p[i].Ts[3] = (min / 10) + '0';
        p[i].Ts[4] = (min % 10) + '0';
    }
}

// 计算周转时间
void calcuTar(){
    for(int i = 1; i < 5; i++){
        p[i].Tar = endTime[i] - arriveTime[i];
    }
}

// 进程操作选择
void processOpt(){
    char processOptNum = '+';
    while(processOptNum != '0'){
        processOptMenu(&processOptNum);
        switch (processOptNum){
            case '0':{      //退出
                break;
            }
            case '1':{      //所有进程一起输入
                processInAll();
                break;           
            } 
            case '2':{      //单个进程输入
                char processNum = '+';
                processNumSele(&processNum);
                processInSin(processNum);
                break;
            }
            case '3':{      //修改单个进程属性
                char processNum= '+';
                processNumSele(&processNum);
                processAltSingle(processNum);
                break;
            }
            case '4':{      //输出进程信息
                processPrintAll();
                break;
            }
            case '5':{      //输出单个属性
                attriPrintSingle();    
                break;
            }
            default:
                break;
        }
        system("cls");
    }
}

// 计算带权周转时间
void calcuTTWA(){
    for(int i = 1; i < 5; i++){
        if(p[i].Tr == 0){
            continue;
        }
        p[i].TTWA = (p[i].Tar * 1.0) / p[i].Tr;
    }
}

// 构建进程到达时间队列
void queueInit(){
    // 按照进程到达时间构建队列
    boolean isProSel[5] = {0};      //记录是否被选中，默认没被选中为0
    for(int i = 1; i < 4; i++){
        int curmin = 1500;
        int index = 0;
        for(int j = 1; j < 5; j++){
            if((!isProSel[j]) && arriveTime[j] < curmin){
                curmin = arriveTime[j];
                index = j;
            }
        }
        queue[i] = index;
        isProSel[index] = 1;    //被选中
    }
    queue[4] = 10 - queue[1] - queue[2] - queue[3];
}
